﻿using System;
using Microsoft.Practices.Unity;
using UnityDemo.LoggingUtility;

namespace UnityDemo.DemoCode
{
    public class RegisterAndResolveDemo :IDemo
    {
        public RegisterAndResolveDemo()
        {
            LogerInstance.Logger.Initialize(this);
            try
            {
                RegisterInterfacesAndClass();
                CheckIfInterfaceIsRegistered();
                RegisterNamedInterfacesAndClass();
                RegisterClass();
                RegisterInstance();
                SeeAllRegisteredMemebers();
            }
            catch (Exception ex)
            {
                LogerInstance.Logger.Exception(ex);
            }
        }

        private void RegisterInterfacesAndClass()
        {
            var container = UnityProvider.UnityInstanceProvider.NewUnityInstance;

            //Registering IServiceProvider and its implementing class
            container.RegisterType<IServiceProvider, ServiceProvider>();

            //Resolving instance of IServiceProvider
            var provider = container.Resolve<IServiceProvider>();
            LogerInstance.Logger.Write(provider);
        }

        private void RegisterNamedInterfacesAndClass()
        {
            var container = UnityProvider.UnityInstanceProvider.NewUnityInstance;
            const string instanceName = "NamedInstance";
            container.RegisterType<IServiceProvider, ServiceProvider>();
            container.RegisterType<IServiceProvider, ServiceProvider>(instanceName);

            var instance1 = container.Resolve<IServiceProvider>();
            var instance2 = container.Resolve<IServiceProvider>();
            instance1.Name = "Hello";
            instance2.Name = "Bye bye";
            LogerInstance.Logger.Info(instance1.Name);
            LogerInstance.Logger.Info(instance2.Name);

            var instance3 = container.Resolve<IServiceProvider>();
            var instance4 = container.Resolve<IServiceProvider>(instanceName);
            instance3.Name = "Hello";
            instance4.Name = "Bye bye";
            LogerInstance.Logger.Info(instance3.Name);
            LogerInstance.Logger.Info(instance4.Name);
        }

        private void RegisterClass()
        {
            var container = UnityProvider.UnityInstanceProvider.NewUnityInstance;
            container.RegisterType<ServiceProvider>();
        }

        private void CheckIfInterfaceIsRegistered()
        {
            var container = UnityProvider.UnityInstanceProvider.NewUnityInstance;
            if (!container.IsRegistered<IServiceProvider>())
            {
                LogerInstance.Logger.Warn("Interface is not registered");
                container.RegisterType<IServiceProvider, ServiceProvider>();
            }
            var provider = container.Resolve<IServiceProvider>();
            LogerInstance.Logger.Write(provider);
        }

        private void RegisterInstance()
        {
            var providerInstance = new ServiceProvider();
            var container = UnityProvider.UnityInstanceProvider.NewUnityInstance;
            container.RegisterInstance<IServiceProvider>(providerInstance);
            var provider = container.Resolve<IServiceProvider>();
            LogerInstance.Logger.Write(provider);
        }

        private void SeeAllRegisteredMemebers()
        {
            var container = UnityProvider.UnityInstanceProvider.ApplicationWideUnityInstance;
            var members = container.Registrations;
            foreach (var registeredMember in members)
            {
                LoggingUtility.LogerInstance.Logger.Write(registeredMember.MappedToType.AssemblyQualifiedName);
            }
        }
    }
}